package com.sx.admin.config;

import com.sx.admin.security.SecurityWebSessionManager;
import com.sx.admin.shiro.QuartzSessionValidationScheduler;
import com.sx.admin.shiro.SecurityFormAuthenticationFilter;
import com.sx.admin.shiro.SecuritySystemAuthorizingRealm;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.mgt.ValidatingSessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.quartz.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
	private static final Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

	@Bean
    public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		shiroFilterFactoryBean.setLoginUrl("/login");
		shiroFilterFactoryBean.setSuccessUrl("/main");
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");


		Map<String, Filter> filters=new HashMap<>();
		filters.put("authc",securityFormAuthenticationFilter());

		LogoutFilter logoutFilter=new LogoutFilter();
		logoutFilter.setRedirectUrl("/login");

		filters.put("logout",logoutFilter);

		shiroFilterFactoryBean.setFilters(filters);

		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String,String>();


		filterChainDefinitionMap.put("/login", "authc");
		filterChainDefinitionMap.put("/logout", "logout");
		filterChainDefinitionMap.put("/main", "authc");
		filterChainDefinitionMap.putAll(filterChainDefinitionMap());

		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}

	/**
	 * /login = authc
	 /logout = logout
	 /main = authc
	 /pl/** = authc
	 /plat/** = authc
	 * @return
	 */
	public  Map<String, String> filterChainDefinitionMap(){
		Map<String, String> map=new HashMap<>();
		map.put("/pl/**","authc");
		map.put("/plat/**","authc");


		return map;

	}
	@Bean
	public SecurityFormAuthenticationFilter securityFormAuthenticationFilter(){
		return new SecurityFormAuthenticationFilter();
	}
	@Bean
	public SecuritySystemAuthorizingRealm securitySystemAuthorizingRealm(CacheManager cacheManager) {
		SecuritySystemAuthorizingRealm securitySystemAuthorizingRealm=new SecuritySystemAuthorizingRealm();
		securitySystemAuthorizingRealm.setCacheManager(cacheManager);
		return securitySystemAuthorizingRealm;
	}


	/**
	 * shiro安全管理器设置realm认证和ehcache缓存管理
	 * @return
	 */
	@Bean
	public org.apache.shiro.mgt.SecurityManager securityManager(ValidatingSessionManager sessionManager,CacheManager cacheManager) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		// 设置realm.
		securityManager.setRealm(securitySystemAuthorizingRealm(cacheManager));

		securityManager.setSessionManager(sessionManager);
		return securityManager;
	}


	@Bean
	public ValidatingSessionManager sessionManager(Scheduler quartzScheduler) {

		DefaultWebSessionManager sessionManager=new SecurityWebSessionManager();
		sessionManager.setGlobalSessionTimeout(9600000l);
		sessionManager.setDeleteInvalidSessions(true);
		sessionManager.setSessionValidationSchedulerEnabled(true);
		sessionManager.setSessionIdCookieEnabled(true);

//		sessionManager.setCacheManager(shiroCacheManager(cacheManager));

		EnterpriseCacheSessionDAO sessionDAO=new EnterpriseCacheSessionDAO();
		sessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");


		sessionDAO.setSessionIdGenerator(new JavaUuidSessionIdGenerator());

		sessionManager.setSessionDAO(sessionDAO);

		SimpleCookie cookie=new SimpleCookie("mldn-session-id");
		cookie.setHttpOnly(true);
		cookie.setMaxAge(-1);

		sessionManager.setSessionIdCookie(cookie);

		QuartzSessionValidationScheduler scheduler=new QuartzSessionValidationScheduler();
		scheduler.setSessionValidationInterval(7200000l);
		scheduler.setSessionManager(sessionManager);
		scheduler.setScheduler(quartzScheduler);
		sessionManager.setSessionValidationScheduler(scheduler);
		return sessionManager;
	}
	@Bean
	public CacheManager shiroCacheManager(net.sf.ehcache.CacheManager manager){
		EhCacheManager ehCacheManager=new EhCacheManager();
		ehCacheManager.setCacheManager(manager);
		return ehCacheManager;
	}


	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}





}

